struct block_device *bdev;
};
+struct backend_info;
+
typedef struct blkif_st {
/* Unique identifier for this interface. */
domid_t domid;
/* Comms information. */
blkif_back_ring_t blk_ring;
struct vm_struct *blk_ring_area;
- /* VBDs attached to this interface. */
+ /* The VBD attached to this interface. */
struct vbd vbd;
+ /* Back pointer to the backend_info. */
+ struct backend_info *be;
/* Private fields. */
enum { DISCONNECTED, CONNECTED } status;
#ifdef CONFIG_XEN_BLKDEV_TAP_BE
irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
+void update_blkif_status(blkif_t *blkif);
+
#endif /* __BLKIF__BACKEND__COMMON_H__ */
/*
blkif->irq = bind_evtchn_to_irqhandler(
blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
- blkif->status = CONNECTED;
+
+ /* We're potentially connected now */
+ update_blkif_status(blkif);
return 0;
}
unsigned int);
+void update_blkif_status(blkif_t *blkif)
+{
+ if(blkif->irq && blkif->vbd.bdev) {
+ blkif->status = CONNECTED;
+ (void)blkif_be_int(0, blkif, NULL);
+ }
+ maybe_connect(blkif->be);
+}
+
+
static ssize_t show_physical_device(struct device *_dev, char *buf)
{
struct xenbus_device *dev = to_xenbus_device(_dev);
be->backend_watch.node = NULL;
}
if (be->blkif) {
+ be->blkif->status = DISCONNECTED;
blkif_put(be->blkif);
be->blkif = NULL;
}
goto fail;
}
+ /* setup back pointer */
+ be->blkif->be = be;
+
err = xenbus_watch_path2(dev, dev->nodename, "physical-device",
&be->backend_watch, backend_changed);
if (err)
device_create_file(&dev->dev, &dev_attr_physical_device);
device_create_file(&dev->dev, &dev_attr_mode);
- maybe_connect(be);
+ /* We're potentially connected now */
+ update_blkif_status(be->blkif);
}
}
if (err) {
return;
}
- maybe_connect(be);
+ update_blkif_status(be->blkif);
break;
case XenbusStateClosing: